<template lang="pug">
  layout-master
    div.bd-w--m(slot="main")
      template(v-if="scoreCriteria.length")
        div.tit
          div.txt {{subjectName}}(课程代码：{{subjectNo}})
          <!--div.btn-refresh(v-on:click="handleClickRefresh")-->
          <!--i-->
          <!--| 刷 新-->
        div.banner
          div.item.item-1
            div.lbl 序号
            div.name {{currentNo}}
          div.item.item-2(v-bind:class="itemActive?'active':''" v-on:mouseenter="handlerMouseEnterBannerItem2($event)" v-on:mouseleave="handlerMouseLeaveBannerItem2($event)")
            div.lbl 考试科目
            div.name 查看
          div.item.item-main
            div.lbl 阅卷下载：
            div.btn
              div.btn-w(v-on:click="handleClickDownload")
        div.main(ref="tableMain")
          template(v-if="tableHeight")
            el-table.table--score-criteria(v-bind:class="isLeaderTeacher?'leader-teacher':''" v-bind:data="scoreCriteria" v-bind:height="tableHeight" border stripe
            v-bind:show-summary="isLeaderTeacher"
              v-bind:summary-method="tableGetSummaries" style="width: 100%")
              el-table-column(prop="name" v-bind:label="`一、实践题（本题共1题，共${subjectPerScore}分）`")
                template(slot-scope="scope") {{scope.$index+1}}. {{scope.row.name}}（{{scope.row.score}}分）
              template(v-if="isLeaderTeacher")
                el-table-column(prop="t1Deduct" label="初阅人" width="113")
                  template(slot-scope="scope")
                    div.mark-f
                      span.icn -
                      | {{scope.row.t1Deduct}}
                el-table-column(prop="t2Deduct" label="副阅人" width="113")
                  template(slot-scope="scope")
                    div.mark-f
                      span.icn -
                      | {{scope.row.t2Deduct}}
              el-table-column(prop="deduct" label="扣 分" v-bind:width="deductWidth")
                template(slot-scope="scope")
                  div.deduct
                    span.icn -
                    input.ipt-deduct(type="number" v-model="scope.row.deduct" v-on:keyup="handlerInputKeyUp($event,scope.row)" v-on:focus="handlerInputFocus" v-on:blur="handlerInputBlur($event,scope.row)")
              el-table-column(label="得 分" v-bind:width="dateWidth")
                template(slot-scope="scope")
                  div.mark {{scope.row.score-scope.row.deduct}}
        div.fter
          div.bx-1
            div.txt
              | 本次试卷共计：
              span.questions-count {{questionsCount}}　
              | 当前试卷：
              span.current-no {{currentNo}}
          div.bx-2
            div.total-score
              span.txt 总&nbsp;分：
              span.score {{totalScore}}
            button.btn-submit(v-on:click="handlerClickSubmit") 确认提交

        div.mask.donwload-loading(v-if="isStartDownload" )
          div.mask-bg
          div.mask-w.donwload-loading-w
            div.txt
              ul
                li
                  div.name 下载试题
                  div.line
                  div.state {{fileProgress*1===100?'完成':fileProgress+'%'}}
                li
                  div.name 解压文件
                  div.line
                  div.state {{decompressState[decompressStateIdx]}}
        div.mask.detail(v-if="itemActive")
          div.mask-bg
          div.mask-w.detail-w
            div.detail-mn
              div.detail-close(v-on:click="handlerClickDetailClose")
              div.detail-cnt
                div.txt-1 {{subjectStem}}
                div.txt-2 一、实践题（共100分）
                div.txt-3
                  template(v-for="(item,idx) in answerConstraint")
                    template(v-if="item.length>0")
                      | {{item}}。
                      br
      template(v-else)
        div.no-list--w
          div.btn-back(v-on:click="handlerClickBtnBack") 返回目录
          div.w-txt
            div.tt 没有找到符合条件的数据
            div.auto-refresh
              | 页面会在
              b {{showSecond}}
              | 秒后自动
              span(v-on:click="handlerClickBtnRefresh")  刷新


</template>

<script type="text/ecmascript-6">
  import LayoutMaster from '../layout/Master'
  import fs from 'fs'
  import Ftp from 'ftp'
  import nodeCmd from 'node-cmd'
  import AdmZip from 'adm-zip'

  export default {
    data() {
      return {
        questList: [],
        downloadMt: null,
        fileProgress: -1,
        deductWidth: 218,
        dateWidth: 300,
        isStartDownload: false,
        decompressStateIdx: 0,
        decompressState: [
          '等待',
          '正在解压',
          '完成'
        ],
        itemActive: false,
        isLeaderTeacher: false,
        userInfo: {},
        subjectPerScore: 100,
        subjectNo: null,
        subjectName: null,
        subjectStem: null,
        tableHeight: 0,
        questionsCount: 100,
        currentNo: null,
        answerConstraint: [],
        /* 评分标准 */
        scoreCriteria: [],
        answerFileName: null,
        /* 自动刷新倒计时 */
        autoRefreshSecond: 60,
        showSecond: 0,
        totalItemScore: 0
      }
    },
    mounted() {
      this.setInfo()
    },
    methods: {
      setInfo() {
        console.log('88 setInfo')
        clearInterval(this.autoMT)
        this.isLeaderTeacher = false
        let _userInfo = this.$KalixCatch.get('USER_INFO')
        if (_userInfo) {
          this.userInfo = JSON.parse(_userInfo)
          this.scoreCriteria = []
          this.subjectName = null
          this.subjectNo = null
          this.getExamData(() => {
            if (!this.scoreCriteria.length) {
              this.autoRefresh()
            }
          })
        }
      },
      /**
       * 刷新按钮点击事件
       */
      handlerClickBtnRefresh() {
        this.setInfo()
      },
      /**
       * 返回目录按钮点击事件
       */
      handlerClickBtnBack() {
        this.$router.replace({name: 'SubjectList'})
      },
      /**
       * 自动刷新
       */
      autoRefresh() {
        console.log('88 autoRefresh')
        this.showSecond = this.autoRefreshSecond
        console.log('88 this.showSecond', this.showSecond)
        this.autoMT = setInterval(() => {
          this.showSecond -= 1
          if (this.showSecond < 0) {
            this.setInfo()
          }
        }, 1000)
      },
      async getExamData(callBack) {
        this.totalItemScore = 0
        let {data: {totalCount, data}} = await this.$http.get(`/camel/rest/examscores/forscore`, {
          params: {
            userId: this.userInfo.userId,
            subjectVal: this.$route.params.subjectVal,
            teacherType: this.$route.params.teacherType,
//            teacherType: this.userInfo.teacherType,
            examId: parseInt(this.$route.params.id)
          }
        })
        if (totalCount > 0) {
          console.log('getExamData 2')
          console.log('data', data)
          let exams = data[0]
          let _scoreCriteria = []
          this.answerConstraint = '根据所提供的参考图，利用3DMAX中的基础模型命令，设计一个会议室的场景图。制作要求: 会议室内不少于3个物件，例如（会议桌、会议椅、投影设备等），物件间的比例要合理，具有一定设计感。'.split('。')
          this.currentNo = exams.examAnswerId
          this.subjectName = exams.subject
          this.subjectStem = exams.stem
          this.subjectNo = exams.subjectVal
          this.subjectPerScore = exams.perScore
          this.answerFileName = exams.answer
          this.isLeaderTeacher = (this.userInfo.teacherType * 1 === 3)
          let _totalItemScore = 0
          exams.examAnswerScoreItems.forEach(item => {
            _scoreCriteria.push({
              name: item.standerItem,
              score: item.itemScore,
              t1Deduct: 0,
              t2Deduct: 0,
              deduct: item.itemDeductScore || 0,
              mark: 1,
              quesId: exams.quesId,
              standerItemId: item.standerItemId
            })
            _totalItemScore += item.itemScore
          })
          this.totalItemScore = _totalItemScore
          if (this.isLeaderTeacher) {
            /* 是组长 */
            this.deductWidth = 120
            this.dateWidth = 120
            let t1 = data[0].teacherType
            data[0].examAnswerScoreItems.forEach((item, i) => {
              let _deduct = data[1].examAnswerScoreItems[i].itemDeductScore || 0
              if (t1 === '1') {
                _scoreCriteria[i].t1Deduct = item.itemDeductScore || 0
                _scoreCriteria[i].t2Deduct = _deduct
              } else {
                _scoreCriteria[i].t1Deduct = _deduct
                _scoreCriteria[i].t2Deduct = item.itemDeductScore || 0
              }
              _scoreCriteria[i].deduct = 0
            })
          } else {
            /* 不是组长 */
            this.deductWidth = 218
            this.dateWidth = 300
          }
          this.scoreCriteria = _scoreCriteria
          this.examScoreDto = {
            examId: exams.examId,
            studentId: exams.studentId,
            teacherId: this.userInfo.userId,
            teacherType: this.userInfo.teacherType,
            score: exams.score,
            examAnswerId: exams.examAnswerId,
            passScore: exams.passScore
          }
          let mt = setTimeout(() => {
            if (this.$refs.tableMain) {
              this.tableHeight = this.$refs.tableMain.clientHeight
            }
            clearTimeout(mt)
          }, 500)
          callBack()
        } else {
          callBack()
        }
      },
      /**
       * 自定义的合计计算方法
       */
      tableGetSummaries(param) {
        const {columns, data} = param
        const sums = []
        sums[0] = ''
        columns.forEach((column, index) => {
          if (index >= 1 && index <= 2) {
            const values = data.map(item => Number(item[column.property]))
            console.log('values', values)
            if (!values.every(value => isNaN(value))) {
              let sum = values.reduce((prev, curr) => {
                const value = Number(curr)
                if (!isNaN(value)) {
                  return prev + curr
                } else {
                  return prev
                }
              })
              sums[index] = `总分：${this.totalItemScore - sum}`
            }
          } else {
            sums[index] = ''
          }
        })
        return sums
      },
      /**
       * 刷新按钮点击事件
       * @private
       */
      handleClickRefresh() {
      },
      /**
       * 关闭提示层
       * @private
       */
      handlerClickDetailClose() {
        this.itemActive = false
      },
      /**
       * 鼠标经过事件
       * @private
       */
      handlerMouseEnterBannerItem2(e) {
        this.mEnterMt = setTimeout(() => {
          this.itemActive = true
          clearTimeout(this.mEnterMt)
        }, 200)
      },
      /**
       * 鼠标离开事件
       * @private
       */
      handlerMouseLeaveBannerItem2(e) {
        clearTimeout(this.mEnterMt)
      },
      /**
       * 提交按钮点击事件
       * @private
       */
      handlerClickSubmit() {
        if (this.examScoreDto) {
          this.$confirm(`<span style="font-size: 34px;color: #ff2b2b;font-weight: bold;margin:0 10px;">${this.totalScore}</span> 分`, '', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            dangerouslyUseHTMLString: true
          }).then(() => {
            let examScoreItemDto = []
            this.scoreCriteria.forEach(item => {
              examScoreItemDto.push({
                quesId: item.quesId,
                standerItemId: item.standerItemId,
                standerItemScore: (item.score - item.deduct),
                itemDeductScore: item.deduct
              })
            })
            this.examScoreDto.examScoreItems = examScoreItemDto
            this.examScoreDto.score = this.totalScore
            console.log('this.examScoreDto', this.examScoreDto)
            this.$http.post('/camel/rest/examscores/score', this.examScoreDto)
              .then(res => {
                this.$alert(res.data.msg, '系统消息', {
                  type: 'success',
                  confirmButtonText: '下一个',
                  callback: () => {
                    this.setInfo()
                  }
                })
              })
          }).catch(() => {
          })
        }
      },
      /**
       * 下载试题按钮点击事件
       * @private
       */
      handleClickDownload() {
        this.fileProgress = -1
        let targetFile = this.answerFileName
        let newFileName = this.currentNo
        let downloadFolder = `${window.KalixConfig.tmpFolder}`
        let downloadFile = `${newFileName}.zip`
        let newFileUrl = downloadFolder + downloadFile
        // 下载文件
        this._downloadFile(targetFile, newFileUrl, err => {
          if (err) {
            this.$alert(`${err.message}<br/>${targetFile}`, '系统提示', {
              type: 'error',
              dangerouslyUseHTMLString: true
            })
            // console.log('err', err.message)
          } else {
            this.isStartDownload = true
            this.decompressStateIdx = 0
            let _mt = null
            clearTimeout(_mt)
            _mt = setTimeout(() => {
              // 解压zip
              this.decompressStateIdx = 1
              let _mt2 = null
              clearTimeout(_mt2)
              _mt2 = setTimeout(() => {
                let _folderUrl = downloadFolder + newFileName + '\\'
                console.log('解压zip', _folderUrl)
                this._decompressFile(newFileUrl, _folderUrl, () => {
                  console.log('解压完成')
                  this.decompressStateIdx = 2
                  let _mt3 = null
                  clearTimeout(_mt3)
                  _mt3 = setTimeout(() => {
                    this.isStartDownload = false
                    this.$confirm(`下载完成, 是否打开文件夹?`, `提示`, {
                      confirmButtonText: '打开',
                      cancelButtonText: '取消',
                      type: 'success'
                    }).then(() => {
                      // 打开被解压文件夹
                      this._openFolder(_folderUrl, () => {
                      })
                    })
                    clearTimeout(_mt3)
                  }, 1000)
                })
                clearTimeout(_mt2)
              }, 1000)
            }, 1000)
          }
        })
      },
      /**
       * 扣分输入框获得焦点事件
       * @param e
       * @param row
       * @private
       */
      handlerInputFocus(e, row) {
        e.target.select()
      },
      /**
       * 扣分输入框失去焦点事件
       * @param e
       * @param row
       * @private
       */
      handlerInputBlur(e, row) {
        row.deduct = Math.abs(e.target.value)
        this._checkScore(e, row)
      },
      /**
       * 扣分输入框按键抬起事件
       * @param e
       * @param row
       * @private
       */
      handlerInputKeyUp(e, row) {
        this._checkScore(e, row)
      },
      /**
       * 下载文件
       * @param targetFile
       * @param callBack
       * @private
       */
      _downloadFile(targetFile, newFileUrl, callBack) {
        clearInterval(this.downloadMt)
        let c = new Ftp()
        c.on('ready', () => {
          let fileList = []
          c.list((err, list) => {
            if (err) {
              c.end()
              callBack(err)
              throw err
            }
            fileList = list
            if (fileList.length) {
              let fileItem = fileList.find(e => {
                return e.name === targetFile
              })
              if (fileItem) {
                c.get(targetFile, (err, fileStream) => {
                  if (err) {
                    callBack(err)
                    c.end()
                    throw err
                  }
                  // fileStream.bytesRead 文件大小
                  fileStream.once('close', () => {
                    console.log('File close')
                    this.fileProgress = 100
                    clearInterval(this.downloadMt)
                    callBack()
                    c.end()
                  })
                  fileStream.pipe(fs.createWriteStream(`${newFileUrl}`))
                  this.downloadMt = setInterval(() => {
                    this.fileProgress = Math.floor((fileStream.bytesRead / fileItem.size) * 100)
                  }, 200)
                })
              } else {
                c.end()
                callBack(new Error('没有找到目标文件'))
              }
            } else {
              clearInterval(this.downloadMt)
              callBack(new Error('没有找到目标文件'))
              c.end()
            }
          })
        })
        c.on(`error`, (err) => {
          c.end()
          callBack(err)
        })
        c.connect({
          host: window.KalixConfig.ftphost,
          user: window.KalixConfig.ftpuser,
          password: window.KalixConfig.ftppwd
        })
      },
      /**
       * 检查输入分值
       * @param e
       * @param row
       * @private
       */
      _checkScore(e, row) {
        if (Math.abs(e.target.value) > row.score) {
          this.$message.error('扣分不能大于得分')
          e.target.select()
        }
      },
      /**
       * 打开文件夹
       * @param targetUrl
       * @param callBack
       * @private
       */
      _openFolder(targetUrl, callBack) {
        nodeCmd.get(`start ${targetUrl}`, err => {
          console.log('文件夹 err', err)
          callBack(err)
        })
      },
      /**
       * 解压文件
       * @param targetUrl
       * @param folderUrl
       * @param callBack
       * @private
       */
      _decompressFile(targetUrl, folderUrl, callBack) {
        try {
          let unzip = new AdmZip(`${targetUrl}`)
          unzip.extractAllTo(`${folderUrl}`, true)
          callBack()
        } catch (e) {
          callBack(e)
        }
      }
    },
    computed: {
      totalScore() {
        let t = 0
        let s = 0
        for (let {score, deduct} of this.scoreCriteria) {
          t += score * 1
          s += deduct * 1
        }
        return t - s
      }
    },
    components: {
      LayoutMaster
    }
  }
</script>

<style scoped lang="stylus" rel="stylesheet/stylus">
  .no-list--w
    height 100%
    display flex
    align-items center
    justify-content center
    position relative

    .btn-back
      position absolute
      cursor pointer
      top 0
      right 0

    .w-txt
      text-align center

      .tt
        font-size 30px
        margin-bottom 20px

      .auto-refresh
        font-size 18px
        color #333333

        b
          margin 0 8px
          font-size 24px
          font-weight normal
          color #003dba

        span
          margin-left 4px
          border-bottom 1px solid #333333

          &:hover
            cursor pointer
            color #000000
            border-bottom 2px solid #000000

  .bd-w--m
    width 970px
    height 100%
    display flex
    flex-direction column
    margin 0 auto
    padding-top 26px

    .tit
      height 37px
      position relative

      &:before
        content ''
        display block
        height 1px
        background-color #eff0f1
        position absolute
        width 100%
        bottom 0
        left 0

      .txt
        color #000000
        background url("../assets/images/icon-10.png") 2px 50% no-repeat
        padding-left 28px
        font-size 14px
        margin-top 13px

      .btn-refresh
        color #ffffff
        background-color #4f8fe3
        border-radius 4px
        width 100px
        height 30px
        line-height 30px
        text-align center
        position absolute
        top 0
        right 0
        cursor pointer
        display flex
        justify-content center
        align-items center

        i
          display block
          width 15px
          height 15px
          margin-right 8px
          background url("../assets/images/icon-11.png") 0 0 no-repeat

    .banner
      height 120px
      display flex
      align-items center

      .item
        width 243px
        height 87px
        border 1px solid transparent
        background-color #f5f5f5
        background 30px 50% no-repeat
        display flex

        & + .item
          margin-left 10px

        &.item-1,
        &.item-2
          flex-direction column
          justify-content center
          align-items flex-end

          .lbl
            font-size 24px
            color #010101

          .name
            font-size 14px
            color #767676
            margin-top 10px

        &.item-1
          background-image url("../assets/images/icon-7.png")
          border-color #5d92f9

          .lbl,
          .name
            width 130px

        &.item-2
          background-image url("../assets/images/icon-8.png")
          border-color #f7ba51

          .lbl,
          .name
            width 150px

          &.active
            position relative
            z-index 9999
            background-color #f5f5f5

        &.item-main
          flex 1
          border-color #56d8c8
          justify-content center
          align-items center

          .lbl
            font-size 18px
            line-height 20px
            height 20px
            color #020202
            background url("../assets/images/icon-9.png") 0 50% no-repeat
            padding-left 35px
            width 135px

          .btn
            background url("../assets/images/btn-bg-1.png") 0 50% no-repeat
            width 219px
            height 53px
            margin-top 4px
            position relative

            .btn-w
              position absolute
              width 207px
              height 41px
              top 3px
              left 4px
              cursor pointer

              &:hover
                background url("../assets/images/btn-bg-1-on.png") 0 0 no-repeat

    .main
      flex 1
      overflow auto

      .mark,
      .mark-f
        text-align center

      .mark-f
        font-size 24px
        color #ff0000

      .deduct
        display flex
        justify-content center

        .icn
          font-size 30px
          color #ff0000
          width 17px
          margin-left -20px

      input.ipt-deduct
        width 48px
        height 26px
        line-height 26px
        padding 0 8px
        outline none
        border 1px solid #ff0000
        color #ff0000
        font-size 22px

        &::-webkit-outer-spin-button,
        &::-webkit-inner-spin-button
          -webkit-appearance none !important
          margin 0

    .fter
      height 163px
      display flex
      padding 18px 0
      box-sizing border-box

      .bx-1
        flex 1

        .txt
          font-size 12px
          color #777777
          padding-left 5px

          span
            font-size 14px

            &.questions-count
              color #41b278

            &.current-no
              color #5ac5e0

      .bx-2
        display flex
        width auto
        flex-direction column
        align-items flex-end

        .total-score
          width 214px
          height 64px
          border-radius 4px
          background-color #f2fbf7
          border 1px solid #97e3c1
          text-align center
          display flex
          justify-content center
          align-items center

          .txt
            font-size 18px
            color #0dac5b
            background url("../assets/images/icon-6.png") 0 50% no-repeat
            padding-left 31px

          .score
            font-size 36px
            color #010101

        .btn-submit
          cursor default
          width 140px
          height 36px
          text-align center
          line-height 36px
          font-size 18px
          color #fffefe
          background-color #ff6c00
          border-radius 4px
          margin-top 25px
          outline none
          border 1px solid #ff6c00

          &:focus
            border-color #FF0E07
            box-shadow 0 0 15px 5px rgba(255, 0, 0, 0.28)

  .prep-score
    position relative
    display flex

    .score-item
      width 113px
      height 36px
      line-height 36px
      font-size 14px
      text-align center
      color #000000

  .mask
    .mask-bg
      position fixed
      top 0
      left 0
      width 100%
      height 100%
      background-color rgba(0, 0, 0, .8)
      z-index 1000

    .mask-w
      position fixed
      z-index 1001
      top 0
      left 0
      width 100%
      height 100%

  .detail
    .detail-w
      .detail-mn
        margin 249px auto 0
        width 937px
        height 336px
        background-color #f6f6f6
        border-radius 4px
        position relative

        .detail-close
          position absolute
          top 15px
          right 19px
          width 18px
          height 18px
          background url("../assets/images/icon-14.png") 0 0 no-repeat
          transition transform .2s linear
          cursor pointer

          &:hover
            transform rotate(180deg)

        &:before
          position absolute
          display block
          width 28px
          height 10px
          content ''
          background url("../assets/images/icon-13.png") 0 0 no-repeat
          top -10px
          left 345px

        .detail-cnt
          padding 30px 66px
          line-height 26px
          font-size 14px
          color #000000

          .txt-1
            font-size 24px
            line-height 36px
            margin-bottom 10px

  .donwload-loading
    .donwload-loading-w
      display flex
      justify-content center
      align-items center

      .txt
        padding 15px 30px
        width 200px
        text-align center
        background-color #ffffff
        box-sizing content-box
        border 2px solid #6d6d6d

        li
          display flex
          align-items center

          & + li
            margin-top 15px

          .name
            font-size 16px

          .line
            flex 1
            height 1px
            background-color #000000
            margin 0 8px

          .state
            font-size 12px
            color #000000

</style>
